﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using log4net;
using log4net.Config;

namespace MLY
{
  internal static class Log
  {
    private const string lineSeperator = "\r\n   ";
    private const int cFileNotExists = -2147467259; // 0x80004005 File does not exist
    private static ILog instance;

    internal static ILog Instance
    {
      get
      {
        if (instance == null)
        {
          log4net.Config.XmlConfigurator.Configure();
          instance = LogManager.GetLogger("File");
        }
        return instance;
      }
    }

    private static void AfterWrite()
    {
      //if (Utils.IsDebug)
      //{
      //  instance = null;
      //  LogManager.Shutdown();
      //}
    }

    internal static void WriteError(object message)
    {
      Instance.Error(message);
      AfterWrite();
    }

    internal static void WriteError(object message, Exception exception)
    {
      Instance.Error(message, exception);
      AfterWrite();
    }

    internal static void WriteInfo(object message)
    {
      Instance.Info(message);
      AfterWrite();
    }

    internal static void WriteDebug(object message)
    {
      Instance.Debug(message);
      AfterWrite();
    }

    internal static void WriteDebug(string message1, string message2)
    {
      if (Instance.IsDebugEnabled)
      {
        Instance.Debug(message1);
        Instance.Debug(message2);
        AfterWrite();
      }
    }

    private static string GetHttpMessage(HttpApplication application, HttpException exception,
                                         out string appRelativeCurrentExecutionFilePath)
    {
      string message = "";
      appRelativeCurrentExecutionFilePath = "";
      if (exception.ErrorCode == cFileNotExists) 
      {
        if (application.Context != null && application.Context.Request != null)
        {
          HttpRequest request = application.Context.Request;
          if (!string.IsNullOrEmpty(request.AppRelativeCurrentExecutionFilePath))
          {
            appRelativeCurrentExecutionFilePath = request.AppRelativeCurrentExecutionFilePath;
            message = lineSeperator + "AppRelativeCurrentExecutionFilePath: \"" + appRelativeCurrentExecutionFilePath + "\"";
          }
          if (request.UrlReferrer != null && !string.IsNullOrEmpty(request.UrlReferrer.AbsolutePath))
            message += lineSeperator + "AbsolutePath: \"" + request.UrlReferrer.AbsolutePath + "\"";
        }
      }
      return message;
    }

    private static void WriteLastError(HttpContext httpContext, object application, Exception exception)
    {
      try
      {
        string message = "";
        string appRelativeCurrentExecutionFilePath;
        if (exception is HttpException && application is HttpApplication)
        {
          HttpException httpException = (HttpException)exception;
          message = GetHttpMessage((HttpApplication)application, httpException, out appRelativeCurrentExecutionFilePath);
          if (httpException.ErrorCode == cFileNotExists &&
              Utils.SameText(appRelativeCurrentExecutionFilePath, "~/LTR/undefined"))
          {
            return;
          }
        }
        if (httpContext != null && httpContext.Request != null && httpContext.Request.Url != null)
        {
          message += lineSeperator + "Url.AbsolutePath: \"" + httpContext.Request.Url.AbsolutePath + "\"";
        }
        WriteError(lineSeperator + exception.ToString() + message);
      }
      catch { }
    }

    internal static void OnPageError(HttpContext httpContext, Exception exception)
    {
      WriteLastError(httpContext, httpContext.ApplicationInstance, exception);
    }

    internal static void OnApplication_Error(object sender, HttpServerUtility server)
    {
      WriteLastError(null, sender, server.GetLastError());
    }

    // Write template id and key fields to log file.
    internal static void LogTemplate(int? templateId, List<string> keyFileds)
    {
      try
      {
        if (Instance.IsDebugEnabled)
        {
          if (templateId.HasValue)
          {
            string keyFieldsStr = "";
            foreach (string keyField in keyFileds)
              keyFieldsStr += keyField + ", ";
            if (keyFieldsStr.Length > 2)
              keyFieldsStr.Substring(1, keyFieldsStr.Length - 2);

            WriteDebug("Template ID: " + templateId.Value.ToString() + " " +
                           "Key Fileds: " + keyFieldsStr);
          }
          else
            WriteDebug("No template");
        }
      }
      catch { }
    }


  }
}